package ArithmeticLibrary.Elements;

import ArithmeticLibrary.Sets.Group;

/**
 * This class represents a mathematical group element. 
 * This class supports group operations: multiplication, division, power, and multiplicative inverse.
 * 
 * @author Lea Golan
 *
 */
public abstract class ElementGroup {
	
	/**
	 * @return the group which the element belongs to
	 */
	public abstract Group getGroup(); 
	
	/**
	 * Compare this to obj by checking equivalence of the value and the set.
	 */
	public abstract boolean equals(java.lang.Object obj); 
	
	/**
	 * Checks if this structure is consistent with obj structure. 
	 * The structure is as follows:
	 * 		For non product elements, it returns true iff obj is an instance of the same class. 
	 * 		For product elements, the function calls to checkStructure of every element from the array of elements it holds
	 * 
	 * @param obj an object we want to check with our structure
	 * @return true iff this and obj are of the same structure
	 */
	public abstract boolean checkStructure(java.lang.Object obj); 

	/**
	 * multiplies this by the value other holds
	 * 
	 * @param other - the element we multiply by
	 * @return a new group element which is the result of multiplying the current element with the other element.
	 * @throws Exception if the mathematical operation fails
	 */
	public abstract ElementGroup multiply(ElementGroup other) throws Exception; 
	
	/**
	 * Returns a new group element which is the result of dividing this element by the other element 
	 * both elements must be in the same group. 
	 * 
	 * @param other - the element we want to divide by
	 * @return a new element that is the result of dividing this to other 
	 * @throws Exception if the mathematical operation fails
	 */
	public abstract ElementGroup divide(ElementGroup other) throws Exception; 
	
	/**
	 * Returns a new group element (can be a product or a simple element)
	 * which is the result of calculating this^exponent.
	 * 
	 * @param exponent - an exponent
	 * @return a new ElementGroup that holds the value this^exponent
	 * @throws Exception if the mathematical operation fails
	 */
	public abstract ElementGroup power(java.math.BigInteger exponent) throws Exception; 
	
	/**
	 * performs inverse operation on the element value with respect to multiplication
	 * 
	 * @return a new group element which is the multiplicative inverse of this
	 * @throws Exception if the mathematical operation fails
	 */
	public abstract ElementGroup multInverse() throws Exception; 
	
}
